using CollabApp.Domain.ValueObjects;

namespace CollabApp.Domain.Services.Game;

/// <summary>
/// 圈地游戏核心逻辑服务接口
/// 实现完整的画线圈地游戏规则，严格按照游戏设计文档执行
/// </summary>
public interface IGameLogicService
{
    #region 核心游戏规则

    /// <summary>
    /// 验证玩家移动是否合法
    /// 检查移动速度、边界限制、碰撞检测等
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">玩家ID</param>
    /// <param name="fromPosition">起始位置</param>
    /// <param name="toPosition">目标位置</param>
    /// <param name="deltaTime">时间间隔（秒）</param>
    /// <param name="isDrawing">是否正在画线</param>
    /// <returns>移动验证结果</returns>
    Task<MoveValidationResult> ValidateMoveAsync(
        Guid gameId,
        Guid playerId,
        Position fromPosition,
        Position toPosition,
        float deltaTime,
        bool isDrawing);

    /// <summary>
    /// 执行轨迹截断检测
    /// 检测玩家轨迹是否与其他玩家的轨迹相交
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">移动玩家ID</param>
    /// <param name="movePath">移动路径</param>
    /// <returns>截断检测结果</returns>
    Task<TrailInterceptionResult> CheckTrailInterceptionAsync(
        Guid gameId,
        Guid playerId,
        List<Position> movePath);

    /// <summary>
    /// 计算圈地面积
    /// 当玩家完成一个闭合路径时，计算新获得的领地面积
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">玩家ID</param>
    /// <param name="closedPath">闭合路径</param>
    /// <param name="existingTerritories">现有领地</param>
    /// <returns>面积计算结果</returns>
    Task<TerritoryCalculationResult> CalculateTerritoryAreaAsync(
        Guid gameId,
        Guid playerId,
        List<Position> closedPath,
        List<Territory> existingTerritories);

    /// <summary>
    /// 处理玩家死亡
    /// 执行死亡逻辑、清除轨迹、计算复活时间
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="victimId">死亡玩家ID</param>
    /// <param name="killerId">击杀玩家ID</param>
    /// <param name="deathPosition">死亡位置</param>
    /// <param name="deathReason">死亡原因</param>
    /// <returns>死亡处理结果</returns>
    Task<PlayerDeathResult> ProcessPlayerDeathAsync(
        Guid gameId,
        Guid victimId,
        Guid? killerId,
        Position deathPosition,
        string deathReason);

    /// <summary>
    /// 处理玩家复活
    /// 执行复活逻辑、设置无敌时间、重置位置
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">玩家ID</param>
    /// <returns>复活处理结果</returns>
    Task<PlayerRespawnResult> ProcessPlayerRespawnAsync(
        Guid gameId,
        Guid playerId);

    #endregion

    #region 道具系统

    /// <summary>
    /// 生成道具
    /// 在地图上随机位置生成道具，避免被领地包围
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="itemType">道具类型</param>
    /// <param name="preferredPosition">偏好位置（可选）</param>
    /// <returns>道具生成结果</returns>
    Task<PowerUpSpawnResult> SpawnPowerUpAsync(
        Guid gameId,
        DrawingGameItemType itemType,
        Position? preferredPosition = null);

    /// <summary>
    /// 处理道具拾取
    /// 验证拾取条件并将道具添加到玩家背包
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">玩家ID</param>
    /// <param name="powerUpId">道具ID</param>
    /// <param name="pickupPosition">拾取位置</param>
    /// <returns>拾取结果</returns>
    Task<PowerUpPickupResult> ProcessPowerUpPickupAsync(
        Guid gameId,
        Guid playerId,
        Guid powerUpId,
        Position pickupPosition);

    /// <summary>
    /// 使用道具
    /// 执行道具效果并更新玩家状态
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">玩家ID</param>
    /// <param name="itemType">道具类型</param>
    /// <param name="targetPosition">目标位置（如适用）</param>
    /// <param name="targetPlayerId">目标玩家（如适用）</param>
    /// <returns>使用结果</returns>
    Task<PowerUpUseResult> UsePowerUpAsync(
        Guid gameId,
        Guid playerId,
        DrawingGameItemType itemType,
        Position? targetPosition = null,
        Guid? targetPlayerId = null);

    #endregion

    #region 地图和边界

    /// <summary>
    /// 检查位置是否在游戏边界内
    /// 支持圆形和矩形地图
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="position">检查位置</param>
    /// <returns>是否在边界内</returns>
    Task<bool> IsPositionInBoundsAsync(Guid gameId, Position position);

    /// <summary>
    /// 获取有效的出生点
    /// 确保出生点不在其他玩家领地内
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">玩家ID</param>
    /// <returns>出生点位置</returns>
    Task<Position> GetValidSpawnPointAsync(Guid gameId, Guid playerId);

    /// <summary>
    /// 检查位置是否在其他玩家领地内
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="position">检查位置</param>
    /// <param name="excludePlayerId">排除的玩家ID</param>
    /// <returns>领地检查结果</returns>
    Task<TerritoryCheckResult> CheckPositionInTerritoryAsync(
        Guid gameId,
        Position position,
        Guid? excludePlayerId = null);

    #endregion

    #region 游戏状态管理

    /// <summary>
    /// 检查游戏结束条件
    /// 检查时间到达、单一玩家统治、最后一人存活等条件
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>游戏结束检查结果</returns>
    Task<GameEndCheckResult> CheckGameEndConditionsAsync(Guid gameId);

    /// <summary>
    /// 计算游戏排名
    /// 基于多维度评分系统计算玩家排名
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>排名结果</returns>
    Task<List<PlayerRankingResult>> CalculateGameRankingAsync(Guid gameId);

    /// <summary>
    /// 更新游戏统计数据
    /// 实时更新各种游戏统计信息
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>更新结果</returns>
    Task<GameStatisticsUpdateResult> UpdateGameStatisticsAsync(Guid gameId);

    #endregion
}

#region 结果类型定义

/// <summary>
/// 移动验证结果
/// </summary>
public class MoveValidationResult
{
    public bool IsValid { get; set; }
    public List<string> Errors { get; set; } = new();
    public Position ValidatedPosition { get; set; } = new();
    public float ActualSpeed { get; set; }
    public bool HasCollisions { get; set; }
    public List<CollisionInfo> Collisions { get; set; } = new();
}

/// <summary>
/// 轨迹截断结果
/// </summary>
public class TrailInterceptionResult
{
    public bool IsIntercepted { get; set; }
    public Position InterceptionPoint { get; set; } = new();
    public Guid InterceptedByPlayerId { get; set; }
    public string InterceptedByPlayerName { get; set; } = string.Empty;
    public List<Position> ClearedTrail { get; set; } = new();
    public bool IsDeadly { get; set; } = true;
}

/// <summary>
/// 领地计算结果
/// </summary>
public class TerritoryCalculationResult
{
    public bool Success { get; set; }
    public float NewAreaGained { get; set; }
    public float TotalArea { get; set; }
    public float AreaPercentage { get; set; }
    public Territory NewTerritory { get; set; } = new();
    public List<Territory> CapturedEnemyTerritories { get; set; } = new();
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 玩家死亡结果
/// </summary>
public class PlayerDeathResult
{
    public bool Success { get; set; }
    public string DeathReason { get; set; } = string.Empty;
    public DateTime DeathTime { get; set; } = DateTime.UtcNow;
    public DateTime RespawnTime { get; set; }
    public List<Position> ClearedTrail { get; set; } = new();
    public GameScore UpdatedScore { get; set; } = GameScore.Zero;
    public bool HasDeathPenalty { get; set; }
}

/// <summary>
/// 玩家复活结果
/// </summary>
public class PlayerRespawnResult
{
    public bool Success { get; set; }
    public Position RespawnPosition { get; set; } = new();
    public DateTime InvulnerabilityEndTime { get; set; }
    public int InvulnerabilityDuration { get; set; } = 5;
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 道具生成结果
/// </summary>
public class PowerUpSpawnResult
{
    public bool Success { get; set; }
    public Guid PowerUpId { get; set; }
    public DrawingGameItemType ItemType { get; set; }
    public Position SpawnPosition { get; set; } = new();
    public DateTime SpawnTime { get; set; } = DateTime.UtcNow;
    public int DurationSeconds { get; set; } = 30;
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 道具使用结果
/// </summary>
public class PowerUpUseResult
{
    public bool Success { get; set; }
    public DrawingGameItemType UsedItem { get; set; }
    public List<Guid> AffectedPlayers { get; set; } = new();
    public ActiveEffect? AppliedEffect { get; set; }
    public Position? TargetPosition { get; set; }
    public List<string> Effects { get; set; } = new();
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 领地检查结果
/// </summary>
public class TerritoryCheckResult
{
    public bool IsInTerritory { get; set; }
    public Guid? TerritoryOwnerId { get; set; }
    public string? TerritoryOwnerName { get; set; }
    public Territory? Territory { get; set; }
    public bool CanDrawHere { get; set; } = true;
    public bool HasSpeedPenalty { get; set; }
}

/// <summary>
/// 游戏结束检查结果
/// </summary>
public class GameEndCheckResult
{
    public bool ShouldEnd { get; set; }
    public string EndReason { get; set; } = string.Empty;
    public Guid? WinnerId { get; set; }
    public string? WinnerName { get; set; }
    public GameEndTrigger Trigger { get; set; }
    public Dictionary<string, object> EndGameData { get; set; } = new();
}

/// <summary>
/// 玩家排名结果
/// </summary>
public class PlayerRankingResult
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public string PlayerColor { get; set; } = string.Empty;
    public int Rank { get; set; }
    public GameScore Score { get; set; } = GameScore.Zero;
    public float TerritoryArea { get; set; }
    public float AreaPercentage { get; set; }
    public bool IsAlive { get; set; } = true;
    public List<string> Achievements { get; set; } = new();
}

/// <summary>
/// 游戏统计更新结果
/// </summary>
public class GameStatisticsUpdateResult
{
    public bool Success { get; set; }
    public Dictionary<Guid, GameScore> PlayerScores { get; set; } = new();
    public Dictionary<string, object> GameStatistics { get; set; } = new();
    public List<string> Changes { get; set; } = new();
}

/// <summary>
/// 碰撞信息
/// </summary>
public class CollisionInfo
{
    public string Type { get; set; } = string.Empty;
    public Position CollisionPoint { get; set; } = new();
    public Guid? OtherPlayerId { get; set; }
    public string Description { get; set; } = string.Empty;
    public bool IsBlocked { get; set; }
    public bool IsDeadly { get; set; }
}

/// <summary>
/// 游戏结束触发原因
/// </summary>
public enum GameEndTrigger
{
    TimeUp,             // 时间到达
    DominationWin,      // 单一玩家占领70%地图
    LastPlayerStanding, // 最后一人存活
    ManualEnd           // 手动结束
}

#endregion
